/**
 *
 */
package jp.seraph.cui;

import org.apache.commons.lang.NullArgumentException;

/**
 * 標準的なANodeTypeを表す抽象実装
 *
 */
public abstract class AbstractNodeType implements SystemNodeType {
    protected AbstractNodeType(String aName) {
        mName = aName;
    }

    private String mName;

    /**
     *
     * @see jp.seraph.cui.SystemNodeType#equals(jp.seraph.cui.SystemNodeType)
     */
    public boolean equals(SystemNodeType aType) {
        if (this.isCommand() != aType.isCommand())
            return false;
        if (this.isData() != aType.isData())
            return false;
        if (this.isMode() != aType.isMode())
            return false;

        return this.getName().equals(aType.getName());
    }

    /**
     *
     * @see jp.seraph.cui.SystemNodeType#isCompatible(jp.seraph.cui.SystemNodeType)
     */
    public boolean isCompatible(SystemNodeType aType) {
        if(aType == null)
            throw new NullArgumentException("aType");

        if(this.equals(aType))
            return true;

        SystemNodeType tSuper = this.getSuperType();
        if(tSuper == null)
            return false;

        return tSuper.isCompatible(aType);
    }

    /**
     *
     * @see jp.seraph.cui.SystemNodeType#isInstance(jp.seraph.cui.SystemNode)
     */
    public boolean isInstance(SystemNode aNode) {
        return aNode.getType().isCompatible(this);
    }

    /**
     * この型のSuperTypeを返す。
     * この型がRootの型である場合null
     *
     * @return
     */
    protected abstract SystemNodeType getSuperType();

    /**
     *
     * @see jp.seraph.cui.SystemNodeType#getName()
     */
    public String getName() {
        return mName;
    }

    /**
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object aObj) {
        if(aObj == null)
            return false;

        if (aObj instanceof SystemNodeType)
            return this.equals((SystemNodeType) aObj);

        return false;
    }

    /**
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        return mName.hashCode();
    }

}
